﻿using System;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.ComponentModel.Composition;
using System.ComponentModel;
using MVVMGrid.UsingReactive.Services;
using MVVMGrid.UsingReactive.Models;
using System.Collections.ObjectModel;

namespace MVVMGrid.UsingReactive.ViewModels
{
    [Export]
    public class GridViewModel : INotifyPropertyChanged, IPartImportsSatisfiedNotification
    {
        [Import]
        public GridService Service { get; set; }

        public GridViewModel()
        {
        }

        private ObservableCollection<GridData> gridDataItems;
        private string errMsg1, errMsg2;
        private ViewSettingsCollection viewSettingsCollection;
        private ViewSettingsCollectionItem selectedSettings;
        private ViewSettings viewSettings;

        public ViewSettingsCollection SettingsCollection
        {
            get { return viewSettingsCollection; }
            set
            {
                viewSettingsCollection = value;
                OnPropertyChanged( "SettingsCollection" );
            }
        }

        public ViewSettingsCollectionItem SelectedSettings
        {
            get { return selectedSettings; }
            set
            {
                selectedSettings = value;
                OnSelectedSettingsChanged();
                OnPropertyChanged( "SelectedSettings" );
            }
        }

        public ViewSettings ViewSettings
        {
            get { return viewSettings; }
            set
            {
                viewSettings = value;
                OnPropertyChanged( "ViewSettings" );
            }
        }

        public ObservableCollection<GridData> DataItems
        {
            get { return gridDataItems; }
            private set
            {
                gridDataItems = value;
                OnPropertyChanged( "DataItems" );
            }
        }

        public string ErrorMessageOne
        {
            get { return errMsg1; }
            private set
            {
                errMsg1 = value;
                OnPropertyChanged( "ErrorMessageOne" );
            }
        }

        public string ErrorMessageTwo
        {
            get { return errMsg2; }
            private set
            {
                errMsg2 = value;
                OnPropertyChanged( "ErrorMessageTwo" );
            }
        }

        private void SetExceptionMessage( Exception ex )
        {
            ErrorMessageOne = String.Concat( "Error: ", ex.GetType().FullName );
            ErrorMessageTwo = ex.Message;
        }

        public event PropertyChangedEventHandler PropertyChanged;

        private void OnPropertyChanged( string propertyName )
        {
            PropertyChangedEventHandler eventHandler = PropertyChanged;
            if( eventHandler != null )
                eventHandler( this, new PropertyChangedEventArgs( propertyName ) );
        }

        public void OnImportsSatisfied()
        {
            Service
                .GetViewSettingsCollection()
                .ObserveOnDispatcher()
                .Subscribe( vsc =>
                {
                    SettingsCollection = vsc;
                    SelectedSettings = SettingsCollection.GetDefaultSettings();
                },
                SetExceptionMessage );

            Service
                .GetGridItems()
                .ObserveOnDispatcher()
                .Subscribe( d =>
                {
                    DataItems = new ObservableCollection<GridData>( d );
                },
                SetExceptionMessage );
        }

        private void OnSelectedSettingsChanged()
        {
            if( SelectedSettings != null )
            {
                Service
                    .GetViewSettings( SelectedSettings )
                    .ObserveOnDispatcher()
                    .Subscribe( vs =>
                    {
                        ViewSettings = vs;
                    },
                    SetExceptionMessage );
            }
        }
    }
}
